<?php

namespace App\Http\Controllers;

use DB;
use Uuid;
use Redis;
use LucaDegasperi\OAuth2Server\Authorizer;

class ArticleController extends CommonController
{
    public function __construct(Authorizer $authorizer)
    {
        parent::__construct($authorizer);

        $this->middleware('oauth', ['except' => ['show', 'commentList', 'report', 'search']]);
        $this->middleware('validation');
    }

    private static $_validate = [
        'comment' => [
            'content' => 'required',
        ],
    ];

    public function show($id)
    {
        $article = $this->getArticleById($id);

        $article->is_starred = $this->isStarred($id);

        $this->title = $article->title;
        $relatedArticle = $this->fetchRelatedArticle($id);

        $topicComment = $this->fetchTopicComment($id);

        return [
            'article' => $article,
            'related_articles' => $relatedArticle,
            'topic_comments' => $topicComment,
        ];
    }

    protected function isStarred($id)
    {
        if (! $this->accessToken) {
            return false;
        }

        $uid = $this->getOwnerId();

        return $this->checkUserArticleStar($uid, $id);
    }

    /**
     * Article tag get from its comment todo
     *
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    protected function fetchRelatedArticle($id)
    {
        $tag = $this->matchTag($this->title);

        if ($tag === '') {
            return [];
        }

        if (strpos($tag, ',') !== false) {
            $tag = strstr($tag, ',', true);
        }

        return $this->articleFieldExceptContent()
            ->where('article_title', 'like', "%{$tag}%")
            ->latest('article_addtime')
            ->take(2)
            ->get();
    }

    protected function fetchTopicComment($articleId)
    {
        $key = "sisi_articles:{$articleId}:comments:favours";

        if (! Redis::exists($key)) {
            $key = "sisi_articles:{$article_id}:comments";
        }

        return $this->fetchCommentList($key);
    }

    public function star($id)
    {
        $uid = $this->authorizer->getResourceOwnerId();

        Redis::zadd("users:{$uid}:stars", time(), "articles:{$id}");

        return ['error' => false];
    }

    public function unstar($id)
    {
        $uid = $this->authorizer->getResourceOwnerId();

        Redis::zrem("users:{$uid}:stars", "articles:{$id}");

        return response('', 204);
    }

    public function comment($id)
    {
        $content = request('content');

        $uid  = $this->authorizer->getResourceOwnerId();
        $user = $this->fetchUser($uid);

        $identifier = Uuid::generate(4)->string;

        $tag = $this->matchTag($content);

        if ($tag !== '') {
            Redis::zadd("tag_names:{$tag}", time(), $identifier);
            $this->setCommentTag("sisi_articles:{$id}:comment_tags", $tag);
        }

        Redis::zadd("sisi_articles:{$id}:comments", time(), $identifier);

        Redis::zadd("users:{$uid}:comments", time(), $identifier);

        $hashData = [
            'id'         => $identifier,
            'content'    => $content,
            'created_at' => date('Y-m-d H:i:s'),
            'user_id'    => $uid,
        ];

        Redis::hmset("comments:{$identifier}", $hashData);

        return array_merge($hashData, ['favours' => 0, 'is_favoured' => false, 'user' => $user]);
    }

    protected function setCommentTag($key, $tag)
    {
        if (strpos($tag, ',') !== false) {
            return;
        }

        if (Redis::zrank($key, $tag) !== null) {
            Redis::zincrby($key, 1, $tag);
        } else {
            Redis::zadd($key, 1, $tag);
        }
    }

    public function commentList($id)
    {
        $comments = $this->fetchCommentList("sisi_articles:{$id}:comments", 4);

        $tag = $this->fetchTagForArticle($id);

        $extraComment = $this->fetchCommentList("tag_names:{$tag}");

        // 过滤其他评论与自身评论的重复
        foreach ($comments as $comment) {
            foreach ($extraComment as $key => $extra) {
                if ($extra['id'] === $comment['id']) {
                    unset($extraComment[$key]);
                }
            }
        }

        return ['list' => $comments, 'extra' => $extraComment];
    }

    public function report()
    {
        return unserialize(Redis::get('api:reports'));
    }

    public function search()
    {
        $q = request('q', '');

        $model = $this->articleFieldExceptContent()
            ->where('article_title', 'like', "%{$q}%")
            ->orWhere('article_writer', 'like', "%{$q}%")
            ->orWhere('article_whoadd', 'like', "%{$q}%");

        $this->addPagination($model);

        return $model->latest('created_at')->get();
    }


}